//: C20:BasicSequenceOperations.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 1999
// Copyright notice in Copyright.txt
// The operations available for all the
// basic sequence Containers.
#include <iostream>
#include <vector>
#include <deque>
#include <list>
using namespace std;

template<typename Container>
void print(Container& c, char* s = "")
{
    cout << s << ":" << endl;
    if (c.empty()) {
        cout << "(empty)" << endl;
        return;
    }
    typename Container::iterator it;
    for (it = c.begin(); it != c.end(); it++)
        cout << *it << " ";
    cout << endl;
    cout << "size() " << c.size()
         << " max_size() "<< c.max_size()
         << " front() " << c.front()
         << " back() " << c.back() << endl;
}

template<typename ContainerOfInt>
void basicOps(char* s)
{
    cout << "------- " << s << " -------" << endl;
    typedef ContainerOfInt Ci;
    Ci c;
    print(c, "c after default constructor");
    Ci c2(10, 1); // 10 elements, values all 1
    print(c2, "c2 after constructor(10,1)");
    int ia[] = { 1, 3, 5, 7, 9 };
    const int iasz = sizeof(ia)/sizeof(*ia);
    // Initialize with begin & end iterators:
    Ci c3(ia, ia + iasz);
    print(c3, "c3 after constructor(iter,iter)");
    Ci c4(c2); // Copy-constructor
    print(c4, "c4 after copy-constructor(c2)");
    c = c2; // Assignment operator
    print(c, "c after operator=c2");
    c.assign(10, 2); // 10 elements, values all 2
    print(c, "c after assign(10, 2)");
    // Assign with begin & end iterators:
    c.assign(ia, ia + iasz);
    print(c, "c after assign(iter, iter)");
    cout << "c using reverse iterators:" << endl;
    typename Ci::reverse_iterator rit = c.rbegin();
    while (rit != c.rend())
        cout << *rit++ << " ";
    cout << endl;
    c.resize(4);
    print(c, "c after resize(4)");
    c.push_back(47);
    print(c, "c after push_back(47)");
    c.pop_back();
    print(c, "c after pop_back()");
    typename Ci::iterator it = c.begin();
    it++;
    it++;
    c.insert(it, 74);
    print(c, "c after insert(it, 74)");
    it = c.begin();
    it++;
    c.insert(it, 3, 96);
    print(c, "c after insert(it, 3, 96)");
    it = c.begin();
    it++;
    c.insert(it, c3.begin(), c3.end());
    print(c, "c after insert("
          "it, c3.begin(), c3.end())");
    it = c.begin();
    it++;
    c.erase(it);
    print(c, "c after erase(it)");
    typename Ci::iterator it2 = it = c.begin();
    it++;
    it2++;
    it2++;
    it2++;
    it2++;
    it2++;
    c.erase(it, it2);
    print(c, "c after erase(it, it2)");
    c.swap(c2);
    print(c, "c after swap(c2)");
    c.clear();
    print(c, "c after clear()");
}

int main()
{
    basicOps<vector<int> >("vector");
    basicOps<deque<int> >("deque");
    basicOps<list<int> >("list");
} ///:~
